#!/bin/bash
#######
## mysql5.6,mysql5.7用
## yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
## percona-release enable-only tools release(可选项,按照实际情况添加)
## yum install -y percona-xtrabackup-24
## 卸载yum remove percona-xtrabackup
#######
##  使用
##  1创建文件夹及其路径 mkdir -p /home/backup/full  &&  mkdir -p /home/backup/incremental   && mkdir -p /home/backup/tar.gzdb  && mkdir -p /home/backup/config
##  2在配置文件中添加/home/backup/config/config
##       backup_full=  ##按照格式填写比当前时间小1天时间,或者不填写
##       backup_pre_name=
##       backup_recent_time=   #最近一次的全量备份时间(年月日)

##  3 bash 进行执行脚本

# 将年月日转换为时间戳
function timeToStamp() {
    echo $(date -d "$1" +%s)
}

#######################
db_user="root"                                       #数据库的用户名
db_passwd="LIANG@liang@12345"                        #数据库的密码
db_databases="a52zhxycn"                             #备份的数据库多个用空格隔开
db_defaults_file="/usr/local/mysql56/my.cnf"         #mysql的配置文件,该配置文件中必须要配置basedir和datadir
db_socket="/tmp/mysql.sock"                          #mysql的tcp通信的sock文件
db_backup="/home/backup/"                            #备份的目录
db_backup_fulldir="/home/backup/full/"               #全量备份
db_backup_incrementaldir="/home/backup/incremental/" #增量备份的文件夹
db_backup_tarfull="/home/backup/tar.gzdb/"           #tar压缩文件
rm_num=7                                             #多少天一个循环

#得到当前时间和配置文件
time="$(date +"back_%Y-%m-%d_%H-%M-%S")"
NOW_DATE="$(date +"%Y-%m-%d")"
source /home/backup/config/config

#用于压缩并转移源文件
move_and_tar() {
    if [ $# != 1 ]; then
        echo "参数不正确"
        exit 0
    fi

    time_rm=$(date -d "$1 days ago" +"back_%d-%m-%Y")

    if [ $1 -eq 7 ]; then
        if [ -d ${db_backup_fulldir}${time_rm} ]; then
            su - root -c "tar -czPvf ${db_backup_tarfull}${time_rm}_full.tar.gz ${db_backup_fulldir}${time_rm}"
            su - root -c "rm -rf ${db_backup_fulldir}${time_rm}"
            echo "压缩目录rm $db_backup_fulldir${time_rm}" >>/home/backup/config/tar.log
        fi
    fi

    if [ $1 -gt 0 -a $1 -lt 7 ]; then
        if [ -d $db_backup_incrementaldir${time_rm} ]; then
            su - root -c "tar -czPvf ${db_backup_tarfull}${time_rm}_increment.tar.gz ${db_backup_incrementaldir}${time_rm}"
            su - root -c "rm -rf ${db_backup_incrementaldir}${time_rm}"
            echo "压缩目录rm $db_backup_incrementaldir${time_rm}" >>/home/backup/config/tar.log
        fi
    fi
}

# 数据库的备份
function backup() {
    if [ -z ${backup_full} ] || [ $(timeToStamp $NOW_DATE) -gt $(timeToStamp ${backup_recent_time}) ]; then
        #todo
        echo '全备份'
        backup_full=${time}
        innobackupex --defaults-file=$db_defaults_file --no-timestamp --user=${db_user} --password=${db_passwd} --databases=${db_databases} --no-lock --socket=$db_socket ${db_backup_fulldir}${NOW_DATE}/${backup_full}/

        if [ $? -eq 0 ]; then
            echo "${time} 全备份成功!!!" >>"/home/backup/config/results-${NOW_DATE}.log"
        else
            echo "${time} 全备份失败???" >>"/home/backup/config/results-${NOW_DATE}.log"
        fi

        #更新配置文件
        echo "backup_full=${backup_full}" >/home/backup/config/config
        echo "backup_pre_name=full/${NOW_DATE}/${backup_full}" >>/home/backup/config/config
        echo "backup_recent_time=${NOW_DATE}" >>/home/backup/config/config

        #自动删除两周以前的备份文件
        while [ ${rm_num} -lt 8 -a ${rm_num} -gt 0 ]; do
            move_and_tar ${rm_num}
            rm_num=$(expr ${rm_num} - 1)
        done

        #进行数据还原后进行压缩,到下一天立马执行
        if [ $(timeToStamp $(date -d "+1 day ${backup_recent_time}" +%Y-%m-%d)) -eq $(timeToStamp $NOW_DATE) ]; then
            RESULTS_LOT="/home/backup/config/results-${NOW_DATE}.log"
            ARRAY=($(awk '{print $1}' ${RESULTS_LOT}))
            index=0
            for i in ${ARRAY[@]}; do
                echo "index:${index}----${i}"
                let index++
            done
        fi

        echo '全备份'
    else
        #todo
        echo '增量备份'

        innobackupex --defaults-file=$db_defaults_file --socket=$db_socket --no-timestamp --user=${db_user} --password=${db_passwd} --databases=${db_databases} --no-lock --incremental ${db_backup_incrementaldir}${NOW_DATE}/${time}/ --incremental-basedir=${db_backup}${backup_pre_name}

        if [ $? -eq 0 ]; then
            echo "${time} 增量备份成功!!!" >>"/home/backup/config/results-${NOW_DATE}.log"
        else
            echo "${time} 增量备份失败???" >>"/home/backup/config/results-${NOW_DATE}.log"
        fi

        #更新配置文件
        echo "backup_full=${backup_full}" >/home/backup/config/config
        echo "backup_pre_name=incremental/${NOW_DATE}/${time}" >>/home/backup/config/config
        echo "backup_recent_time=${NOW_DATE}" >>/home/backup/config/config
        echo '增量备份'
    fi
}
# 备份的还原(明天的某一时刻)
function restore() {
    # RESTORE_DATE=$(date -d "-1 day ${NOW_DATE}" +%Y-%m-%d)
    RESTORE_DATE=$NOW_DATE
    RESULTS_LOT="/home/backup/config/results-${RESTORE_DATE}.log"
    ARRAY=($(awk '{print $1}' ${RESULTS_LOT}))
    index=0
    FIRST_FULL=${ARRAY[0]}
    let LENGTH=${#ARRAY[@]}-1
    cp ${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL} "${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL}-bark" -rf
    for i in ${ARRAY[@]}; do
        if [ ${index} -eq '0' ]; then
            #第一次基于apply-log的一致性  
            innobackupex   --apply-log --redo-only ${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL}/
        else
            #基于全备份一级一级恢复
            if [ ${index} -eq ${LENGTH} ]; then
                #最后一次增量还原
                innobackupex   --apply-log  ${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL}/ --incremental-dir=${db_backup_incrementaldir}${RESTORE_DATE}/${i}/
                innobackupex   --apply-log  ${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL}/
            else
                innobackupex   --apply-log --redo-only ${db_backup_fulldir}${RESTORE_DATE}/${FIRST_FULL}/ --incremental-dir=${db_backup_incrementaldir}${RESTORE_DATE}/${i}/
            fi
            

            if [ $? -ne 0 ]; then
                echo "错了就是错了啊"
                break
            fi
        fi
        let index++
    done
}

if [[ $1 = "backup" ]]; then
    backup
elif [[ $1 = "restore" ]]; then
    restore
fi
